package com.xxxtea.config;

import cn.hutool.core.util.URLUtil;
import com.xxxtea.common.Constants;
import com.xxxtea.config.converter.StringToEnumConverterFactory;
import com.xxxtea.security.AuthInterceptor;
import com.xxxtea.security.AuthProperties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.annotation.Resource;
import java.io.File;

/**
 * Spring Web MVC配置类
 * 
 * 配置静态资源映射、拦截器、路径前缀、类型转换等Web相关功能。
 * - 静态资源映射：将本地文件目录和前端dist目录映射为URL资源
 * - 拦截器注册：注册认证拦截器，支持白名单配置
 * - 路径前缀：为API接口统一添加前缀
 * - 类型转换：支持字符串到枚举的自动转换
 * 
 * @author badman
 * @since 1.0.0
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
	/**
	 * 文件存储目录
	 */
	@Value("${fileDir}")
	private File fileDir;
	/**
	 * 前端dist目录
	 */
	@Value("${distDir}")
	private File distDir;
	/**
	 * 认证属性配置
	 */
	@Resource
	private AuthProperties authProperties;
	/**
	 * 认证拦截器
	 */
	@Resource
	private AuthInterceptor authInterceptor;

	/**
	 * 配置静态资源映射
	 * 将本地文件目录和前端dist目录映射为URL资源路径
	 */
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		// 映射文件上传目录
		registry.addResourceHandler("/file/**")
				.addResourceLocations(URLUtil.getURL(fileDir).toString());
		// 映射前端静态资源目录
		registry.addResourceHandler("/**")
				.addResourceLocations(URLUtil.getURL(distDir).toString());
	}

	/**
	 * 注册认证拦截器
	 * 对/api/**路径进行拦截，支持白名单放行
	 */
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(authInterceptor)
				.addPathPatterns("/api/**")
				.excludePathPatterns(authProperties.getWhiteUrlList());
	}

	/**
	 * 配置API路径前缀
	 * 为指定包下的Controller统一添加/api前缀
	 */
	@Override
	public void configurePathMatch(PathMatchConfigurer configurer) {
		configurer.addPathPrefix("/api", clazz -> clazz.getName().contains(Constants.BASE_PACKAGE));
	}

	/**
	 * 注册类型转换器工厂
	 * 支持字符串到枚举类型的自动转换
	 */
	@Override
	public void addFormatters(FormatterRegistry registry) {
		registry.addConverterFactory(new StringToEnumConverterFactory());
	}
}